home *** CD-ROM | disk | FTP | other *** search
- /* Sender and Reciever are simple AppleEvent programs that demonstrate */
- /* all the permutations of interaction levels for sending */
- /* and recieving APpleEvents. */
- /* Have fun with them. */
- /* P.S. This also uses PBCatSearch, so I've done the typing for you if you've wanted */
- /* to use this call but have been confused by the param block */
- /* C.K. Haun */
- /* Apple DTS */
- /* this sends the simple event */
-
-
- #include <Types.h>
- #include <memory.h>
- #include <Packages.h>
- #include <Errors.h>
- #include <quickdraw.h>
- #include <fonts.h>
- #include <dialogs.h>
- #include <windows.h>
- #include <menus.h>
- #include <events.h>
- #include <OSEvents.h>
- #include <Desk.h>
- #include <diskinit.h>
- #include <OSUtils.h>
- #include <resources.h>
- #include <toolutils.h>
- #include <AppleEvents.h>
- #include <EPPC.h>
- #include <GestaltEqu.h>
- #include <PPCToolbox.h>
- #include <Processes.h>
- /* prototypes */
- void DoDiskEvents(long dinfo); /* hi word is error code, lo word is drive number */
- void DrawMain(WindowPtr drawIt);
- Boolean DoSelected(long val);
- pascal Boolean idleProc(EventRecord *eventIn, long *sleep, RgnHandle *mouseRgn);
- void InitAEStuff(void);
- void DoHighLevel(EventRecord *AERecord);
- void DoDaCall(MenuHandle themenu, long theit);
- OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- OSErr AEReplyHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- void SendSimple(void);
- OSErr FindReciever(AEDesc *theAddress);
- #define kSwitchItem 5
- #define kReplyItem 7
- short gSendInteractArray[4] =
- {
- nil, kAENeverInteract, kAECanInteract, kAEAlwaysInteract,
- };
-
-
-
- short replyLevels[] =
- {
- kAENoReply, kAEWaitReply,kAEQueueReply
- };
-
-
- short replyValue = 0;
-
- short gInteract = 1;
- short gSwitchLayer = false;
- LaunchParamBlockRec launchThis;
-
- #define kMBarID 128
- #define kAppleMenu 128
- #define kFileMenu 129
- #define kEditMenu 130
- #define kToolsMenu 131
- #define kSendButton 128
- #define kResumeMask 1 /* bit of message field for resume vs. suspend */
- #define kBadCombo 129
- #define kNoFind 130
- #define kSearch 200
- MenuHandle gAppleMenuHandle, gFileMenuHandle, gEditMenuHandle, gToolMenuHandle;
- Handle gMymenu; /* my menu bar handle */
- ControlHandle sendButton;
-
- AEAddressDesc targetAddress; /* address of the person to get the data from */
-
-
- #ifdef powerc
- QDGlobals qd;
- #endif
-
- #define kSimpleEvent 'SIMP'
- #define kSimpleClass 'Simp'
- Boolean gQuit, gInBackground;
- EventRecord gERecord;
- AEDesc gTheAddress;
- AEIdleUPP gAEIdleUPP;
- WindowPtr myWindow;
- main()
- {
- WindowPtr twindow;
- ControlHandle returnedControl;
- MaxApplZone();
- InitGraf((Ptr)&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- InitAEStuff();
- /* set up my menu junk */
- gMymenu = GetNewMBar(kMBarID);
- SetMenuBar(gMymenu);
- gAppleMenuHandle = GetMenuHandle(kAppleMenu);
- gFileMenuHandle = GetMenuHandle(kFileMenu);
- gEditMenuHandle = GetMenuHandle(kEditMenu);
- gToolMenuHandle = GetMenuHandle(kToolsMenu);
- CheckItem(gToolMenuHandle, gInteract, true);
- CheckItem(gToolMenuHandle, replyValue+kReplyItem, true);
- AppendResMenu(gAppleMenuHandle, 'DRVR');
-
-
-
- /* this finds and launches the receiver */
- if(FindReciever(&gTheAddress) != noErr){
- StopAlert(kNoFind,nil);
- ExitToShell();}
- DrawMenuBar();
- myWindow = GetNewWindow(128, nil, (WindowPtr)-1);
- GetNewControl(kSendButton, myWindow);
- do {
- WaitNextEvent(everyEvent, &gERecord, 30, nil);
- switch (gERecord.what) {
-
- case nullEvent:
- /* no nul processing in this sample */
- break;
- case updateEvt:
- DrawMain((WindowPtr)gERecord.message); /* draw whatever window needs an update */
- break;
- case mouseDown:
- /* first see where the hit was */
- switch (FindWindow(gERecord.where, &twindow)) {
-
- case inDesk: /* if they hit in desk, then the process manager */
- break; /* will switch us out, we don't need to do anything */
- case inMenuBar:
- DoSelected(MenuSelect(gERecord.where));
- break;
-
- case inSysWindow:
- /* pass to the system */
- SystemClick(&gERecord, twindow);
- break;
- case inContent:
- GlobalToLocal(&gERecord.where);
- /* track my button as needed */
- if (FindControl(gERecord.where, twindow, &returnedControl)) {
- if (TrackControl(returnedControl, gERecord.where, nil)) {
- SendSimple();
- }
- }
- break;
- case inDrag:
- if (twindow == FrontWindow())
- DragWindow(twindow, gERecord.where, &qd.screenBits.bounds);
- break;
- case inGrow:
- case inGoAway:
- /* don't care */
- break;
-
- }
- case mouseUp:
- /* don't care */
- break;
- /* same action for key or auto key */
- case keyDown:
- case autoKey:
- if (gERecord.modifiers & cmdKey)
- DoSelected(MenuKey(gERecord.message & charCodeMask));
- break;
- case keyUp:
- /* don't care */
- break;
- case diskEvt:
- /* I don't do anything special for disk events, this just passes them */
- /* to a function that checks for an error on the mount */
- DoDiskEvents(gERecord.message);
- break;
- case activateEvt:
- if (gERecord.modifiers & activeFlag)
- DrawMain((WindowPtr)gERecord.message);
- break;
- case networkEvt:
- /* don't care */
- break;
- case driverEvt:
- /* don't care */
- break;
- case app4Evt:
- switch ((gERecord.message >> 24) & 0x0FF) { /* high byte of message */
- case suspendResumeMessage: /* suspend/resume is also an activate/deactivate */
- gInBackground = (gERecord.message & kResumeMask) == 0;
- break;
- }
- break;
- default:
- break;
- /* This dispatches high level events (AppleEvents, for example) */
- /* to our dispatch routine. This is NEW in the event loop for */
- /* System 7 */
- case kHighLevelEvent:
- DoHighLevel(&gERecord);
- break;
-
- }
- } while (gQuit != true);
-
-
- }
-
- /* DoDaCall opens the requested DA. It's here as a seperate routine if you'd */
- /* like to perform some action or just know when a DA is opened in your */
- /* layer. Can be handy to track memory problems when a DA is opened */
- /* with an Option-open */
- void DoDaCall(MenuHandle themenu, long theit)
- {
- long qq;
- char DAname[255];
- GetMenuItemText(themenu, theit, &DAname);
- qq = OpenDeskAcc(DAname);
- }
-
- /* end DoDaCall */
-
- /* DoDiskEvents just checks the error code from the disk mount, */
- /* and puts up the 'Format' dialog (through DIBadMount) if need be */
- /* You can do much more here if you care about what disks are */
- /* in the drive */
- void DoDiskEvents(long dinfo) /* hi word is error code, lo word is drive number */
- {
- short hival, loval, tommy;
- Point fredpoint = {
- 40, 40
- };
- hival = HiWord(dinfo);
- loval = LoWord(dinfo);
- if (hival != noErr) /* something happened */ {
- tommy = DIBadMount(fredpoint, dinfo);
- }
- }
-
- /* draws my window. Pretty simple */
- void DrawMain(WindowPtr drawIt)
- {
- BeginUpdate(drawIt);
- SetPort(drawIt);
- DrawControls(drawIt);
- EndUpdate(drawIt);
- }
-
- /* my menu action taker. It returns a Boolean which I usually ignore, but it */
- /* mught be handy someday */
- Boolean DoSelected(long val)
- {
- short loval, hival;
- Boolean temp = false;
- loval = LoWord(val);
- hival = HiWord(val);
-
- switch (hival) { /* switch off the menu number selected */
- case kAppleMenu: /* Apple menu */
- if (loval != 1) { /* if this was not About, it's a DA */
- DoDaCall(gAppleMenuHandle, loval);
- } else {
- Alert(128, nil); /* do about box */
- }
- break;
- case kFileMenu: /* File menu */
- gQuit = true; /* only item */
- break;
- case kEditMenu:
- /* edit menu junk */
- /* don't care */
- break;
- /* This is the interaction level menu, sets checks and variables */
- case kToolsMenu:
- if (loval == kSwitchItem) {
- if (gSwitchLayer) gSwitchLayer = false;
- else gSwitchLayer = kAECanSwitchLayer;
-
- CheckItem(gToolMenuHandle, kSwitchItem, gSwitchLayer);
- } else {
- if (loval >= kReplyItem) {
- if(loval != replyValue){
-
- CheckItem(gToolMenuHandle, replyValue+kReplyItem, false);
- CheckItem(gToolMenuHandle,loval,true);
- replyValue = loval - kReplyItem;}
- } else {
- if (gInteract != loval) {
- CheckItem(gToolMenuHandle, gInteract, false);
- CheckItem(gToolMenuHandle, loval, true);
- gInteract = loval;
- }
- }
- }
- break;
- }
- HiliteMenu(0);
- }
-
- /* InitAEStuff installs my appleevent handlers */
- void InitAEStuff(void)
- {
- OSErr aevtErr = noErr;
- long aLong = 0;
- Boolean gHasAppleEvents = false;
- /* Check this machine for AppleEvents. If they are not here (ie not 7.0)
- * then we exit */
- gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
- /* The following series of calls installs all our AppleEvent Handlers.
- * These handlers are added to the application event handler list that
- * the AppleEvent manager maintains. So, whenever an AppleEvent happens
- * and we call AEProcessEvent, the AppleEvent manager will check our
- * list of handlers and dispatch to it if there is one.
- */
- if (gHasAppleEvents) {
- aevtErr = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
- NewAEEventHandlerProc(AEOpenHandler),0, false);
- if (aevtErr) ExitToShell();
-
- aevtErr = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
- NewAEEventHandlerProc(AEOpenDocHandler),0, false);
- if (aevtErr) ExitToShell();
-
- aevtErr = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
- NewAEEventHandlerProc(AEQuitHandler), 0, false);
- if (aevtErr) ExitToShell();
-
- aevtErr = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
- NewAEEventHandlerProc(AEPrintHandler),0, false);
- if (aevtErr) ExitToShell();
-
- aevtErr = AEInstallEventHandler(kCoreEventClass, kAEAnswer,
- NewAEEventHandlerProc(AEReplyHandler),0, false);
- if (aevtErr) ExitToShell();
-
- if (aevtErr) ExitToShell();
-
- /* create a UPP for the AppleEvent idle proc */
- gAEIdleUPP = NewAEIdleProc(idleProc);
-
- }
- else ExitToShell();
-
- }
- /* end InitAEStuff */
-
-
- /* I'm not doing error handling in this sample for clarities sake, you should. Hah, */
- /* easy for me to say, huh? */
- void DoHighLevel(EventRecord *AERecord)
- {
-
- AEProcessAppleEvent(AERecord);
-
- }
-
- /* end DoHighLevel */
-
- /* This is the standard Open Application event. */
- OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (messagein,reply,refIn)
- /* we of course don't do anything here in this simple app */
- return(noErr);
- }
-
- /* end AEOpenHandler */
-
- /* Open Doc, opens our documents. Remember, this can happen at application start AND */
- /* anytime else. If your app is up and running and the user goes to the desktop, hilites one */
- /* of your files, and double-clicks or selects Open from the finder File menu this event */
- /* handler will get called. Which means you don't do any initialization of globals here, or */
- /* anything else except open then doc. */
- /* SO-- Do NOT assume that you are at app start time in this */
- /* routine, or bad things will surely happen to you. */
-
- OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (reply, refIn)
- /* we of course don't do anything here */
- return(errAEEventNotHandled); /* we have no docs, so no odoc events should come to us */
- }
-
- OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- { /* no printing handler in yet, so we'll ignore this */
- /* the operation is functionally identical to the ODOC event, with the additon */
- /* of calling your print routine. */
- #pragma unused (reply,refIn)
- /* we of course don't do anything here */
- return(errAEEventNotHandled); /* we have no docs, so no pdoc events should come to us */
- }
-
- /* Standard Quit event handler, to handle a Quit event from the Finder, for example. */
- /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life. */
- OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (messagein,refIn)
-
- /* prepQuit sets the Stop flag for us. It does _NOT_ quit, you */
- /* should NEVER quit from an AppleEvent handler. Calling */
- /* ExitToShell here would blow things up */
- gQuit = true;
- return(noErr);
- }
- /* ReplyHandler is used when I've used QueueReply, which means that the */
- /* reply will come in through my event loop */
- OSErr AEReplyHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (messagein,refIn)
- return(noErr);
- }
- /* SendSimple sends our simple event. About simplest demo of an AESEnd */
- void SendSimple(void)
- {
- AppleEvent ourEvent,ourReply;
- short sendIt = 2;
- AECreateAppleEvent(kSimpleClass, kSimpleEvent, &gTheAddress, kAutoGenerateReturnID, kAnyTransactionID, &ourEvent);
- if (replyLevels[replyValue] == kAEWaitReply && !gSwitchLayer) {
- sendIt = StopAlert(kBadCombo, nil);
- }
- if (sendIt == 2) {
- AESend(&ourEvent, &ourReply, (gSendInteractArray[gInteract] + gSwitchLayer) + replyLevels[replyValue], kAENormalPriority,
- kAEDefaultTimeout,gAEIdleUPP, nil);
- }
- AEDisposeDesc(&ourEvent);
- if(replyLevels[replyValue] == kAEWaitReply)AEDisposeDesc(&ourReply);
- }
-
- /* I'm just launching it, not searching for a port */
- /* I use PBCatSearch to search for it's creator and file type. */
- OSErr FindReciever(AEDesc *theAddress)
- {
- OSErr myError;
- DialogPtr search = GetNewDialog(kSearch,nil,(WindowPtr)-1);
- CSParamPtr csBlockPtr = NewPtrClear(sizeof(CSParam));
- long dirIDUnused;
- Str32 nulString = "\p";
- /* initialize the parameter block */
- DrawDialog(search);
- if (csBlockPtr) {
- csBlockPtr->ioSearchInfo1 = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
- csBlockPtr->ioSearchInfo2 = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
- if (csBlockPtr->ioSearchInfo1 && csBlockPtr->ioSearchInfo2) {
- csBlockPtr->ioMatchPtr = (FSSpecPtr)NewPtrClear(sizeof(FSSpec) * 1); /* only looking for 1 */
- if (csBlockPtr->ioMatchPtr) {
- /* Now see if we can create an optimization buffer */
- csBlockPtr->ioOptBuffer = NewPtr(2048);
- if (csBlockPtr->ioOptBuffer)
- csBlockPtr->ioOptBufSize = 2048;
- else
- csBlockPtr->ioOptBufSize = 0; /* no buffer, sorry */
- csBlockPtr->ioReqMatchCount = 1;
- csBlockPtr->ioSearchTime = 0; /* no timeout */
- }
- }
- }
- HGetVol(nil, &csBlockPtr->ioVRefNum, &dirIDUnused); /* get default volume for search */
- csBlockPtr->ioSearchInfo1->hFileInfo.ioNamePtr = nil;
- csBlockPtr->ioSearchInfo2->hFileInfo.ioNamePtr = nil;
- csBlockPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdCreator = 'MuuB';
- csBlockPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdType = 'APPL';
- csBlockPtr->ioSearchBits = fsSBFlFndrInfo;
- csBlockPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdCreator = 0xFFFFFFFF;
- csBlockPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdType = 0xFFFFFFFF;
-
- myError = PBCatSearch(csBlockPtr, false); /* search sync */
- if (myError == noErr && csBlockPtr->ioActMatchCount != 0) {
- /* we found it, so launch it */
-
- launchThis.launchBlockID = extendedBlock;
- launchThis.launchEPBLength = extendedBlockLen;
- launchThis.launchFileFlags = nil;
- launchThis.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch;
- launchThis.launchAppSpec = &csBlockPtr->ioMatchPtr[0];
- myError = LaunchApplication(&launchThis);
- if (myError == noErr) {
- /* it launched fine. we can use the PSN to make a target */
- AECreateDesc(typeProcessSerialNumber, (Ptr)&launchThis.launchProcessSN, sizeof(ProcessSerialNumber), theAddress);
-
- }
- }
-
- /* no matter what happened, kill the memory we had allocated */
- if (csBlockPtr) {
- if (csBlockPtr->ioSearchInfo1)
- DisposePtr((Ptr)csBlockPtr->ioSearchInfo1);
- if (csBlockPtr->ioSearchInfo2)
- DisposePtr((Ptr)csBlockPtr->ioSearchInfo2);
- if (csBlockPtr->ioMatchPtr)
- DisposePtr((Ptr)csBlockPtr->ioMatchPtr);
- if (csBlockPtr->ioOptBuffer)
- DisposePtr((Ptr)csBlockPtr->ioOptBuffer);
- DisposePtr((Ptr)csBlockPtr);
- }
-
- /* catsearch section end */
- DisposeDialog(search);
- return(myError);
- }
- /* My IdleProc for AESend */
- pascal Boolean idleProc(EventRecord *eventIn, long *sleep, RgnHandle *mouseRgn)
- {
- switch (eventIn->what) {
- case nullEvent:
- /* no nul processing in this sample */
- *sleep = 0;
- mouseRgn = nil;
- break;
- case updateEvt:
- case activateEvt:
- DrawMain((WindowPtr)eventIn->message); /* draw whatever window needs an update */
- break;
- case app4Evt:
- switch ((gERecord.message >> 24) & 0x0FF) { /* high byte of message */
- case suspendResumeMessage: /* suspend/resume is also an activate/deactivate */
- gInBackground = (gERecord.message & kResumeMask) == 0;
- break;
- }
- break;
-
-
-
- }
- return(false); /* I'll wait forever */
- }
-